package com.library.launcher;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * @author : Zach
 * @desc : 启动器
 * @date : 2021/11/9 15:24
 */
public final class Launcher {

    private static final String TAG = "Launcher";

    private Intent mIntent;
    private Context mContext;

    /**
     * androidx下的Fragment
     */
    private RouterFragmentX mRouterFragmentX;
    /**
     * 标准SDK下的Fragment
     */
    private RouterFragment mRouterFragment;

    public Launcher(FragmentActivity activity) {
        mContext = activity;
        mIntent = new Intent();
        mRouterFragmentX = getRouterFragmentX(activity);
    }

    public Launcher(Activity activity) {
        mContext = activity;
        mIntent = new Intent();
        mRouterFragment = getRouterFragment(activity);
    }

    public Launcher setData(Uri uri) {
        mIntent.setData(uri);
        return this;
    }

    public Launcher targetActivity(Class<?> target) {
        mIntent.setClass(mContext, target);
        return this;
    }

    public Launcher withInt(String key, int value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withBoolean(String key, boolean value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withString(String key, String value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withLong(String key, long value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher setAction(String action) {
        mIntent.setAction(action);
        return this;
    }

    public Launcher setFlags(int flags) {
        mIntent.setFlags(flags);
        return this;
    }

    public Launcher withBundle(Bundle bundle) {
        mIntent.putExtras(bundle);
        return this;
    }

    public Launcher withChar(String key, char value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, char[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, boolean[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, long[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, int[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withShort(String key, short value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, short[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withDouble(String key, double value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, double[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withFloat(String key, float value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, float[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withByte(String key, byte value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, byte[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, String[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withParcelable(String key, Parcelable value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withArray(String key, Parcelable[] value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withSerializable(String key, Serializable value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withIntArrayList(String key, ArrayList<Integer> value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withStringArrayList(String key, ArrayList<String> value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher withParcelableArrayList(String key, ArrayList<Parcelable> value) {
        mIntent.putExtra(key, value);
        return this;
    }

    public Launcher addFlags(int flags) {
        mIntent.addFlags(flags);
        return this;
    }

    private RouterFragmentX getRouterFragmentX(FragmentActivity activity) {
        RouterFragmentX routerFragment = findRouterFragmentX(activity);
        if (routerFragment == null) {
            routerFragment = RouterFragmentX.newInstance();
            FragmentManager fragmentManager = activity.getSupportFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .add(routerFragment, TAG)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }
        return routerFragment;
    }

    private RouterFragmentX findRouterFragmentX(FragmentActivity activity) {
        return (RouterFragmentX) activity.getSupportFragmentManager().findFragmentByTag(TAG);
    }

    private RouterFragment getRouterFragment(Activity activity) {
        RouterFragment routerFragment = findRouterFragment(activity);
        if (routerFragment == null) {
            routerFragment = RouterFragment.newInstance();
            android.app.FragmentManager fragmentManager = activity.getFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .add(routerFragment, TAG)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }
        return routerFragment;
    }

    /**
     * 启动
     *
     * @param activity
     * @return
     */
    private RouterFragment findRouterFragment(Activity activity) {
        return (RouterFragment) activity.getFragmentManager().findFragmentByTag(TAG);
    }

    /**
     * intent启动
     */
    public void launch() {
        Log.i(TAG, "launchForResult: " + mIntent.getComponent().getClassName());
        if (mRouterFragmentX != null) {
            mRouterFragmentX.startActivity(mIntent);
        } else if (mRouterFragment != null) {
            mRouterFragment.startActivity(mIntent);
        } else {
            throw new RuntimeException("please do init first!");
        }
    }

    /**
     * 启动
     *
     * @param callback
     */
    public void launch(OnActivityResultListener callback) {
        Log.i(TAG, "launchForResult: " + mIntent.getComponent().getClassName());
        if (mRouterFragmentX != null) {
            mRouterFragmentX.startActivityForResult(mIntent, callback);
        } else if (mRouterFragment != null) {
            mRouterFragment.startActivityForResult(mIntent, callback);
        } else {
            throw new RuntimeException("please do init first!");
        }
    }

}
